/** 编码 操作
  * @param data 代表 编码对象
  * @param type 代表 编码方式
 **/
function replacePer(str: string) {
  return typeof str === 'string' ? str.replace('%', '$per$') : str;
}
export const hexEncode = (data: any = '', type = 'encodeURIComponent'): any => {
  const encodeMethods = {
    encodeURI: (encodeData) => encodeURI(encodeData),
    encodeURIComponent: (encodeData) => encodeURIComponent(encodeData),
  }

  if (typeof data !== 'object') {
    return encodeMethods[type](replacePer(data));

  } else if (Array.isArray(data)) {
    data.forEach((el, i) => {
      data[i] = encodeMethods[type](replacePer(el));
    });

  } else {
    for (const key in data) {
      data[key] = encodeMethods[type](replacePer(data[key]));
    }
  }

  return data;
}

/** 生成随机字符串
 * @param type - [capitalLetter / lowercaseLetter / number] 随机字符串类型
 * @param length - 生成随机字符串长度
 **/
export const randomWord = (type: string[] = ['capitalLetter', 'lowercaseLetter', 'number'], length: number = 3): string => {
  const strOpt = {
    'capitalLetter': ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'],
    'lowercaseLetter': ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'],
    'number': ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
  }
  
  let strMap = [];
  type.forEach(key => {
    strMap = [...strMap, ...strOpt[key]]
  });

  let str = '';
  for (let i = 0; i < length; i++) {
    const index = Math.round(Math.random() * (strMap.length - 1));
    str += strMap[index];
  }
  
  return str
}

/** 常见规则正则校验，返回布尔值
 * @param info 代表 要校验的信息
 * @param sign 代表 要校验信息的规则（传入规则数组或者单个规则字符串）
 **/ 
export const regValidate = (info: string, sign: string | string[]): boolean => {
  const signRegDic = {
    // 常用信息格式
    'phone': /^[1][0-9]{10}$/,  // 手机号
    'email': /^[A-Za-z0-9]+([_\.][A-Za-z0-9]+)*@([A-Za-z0-9\-]+\.)+[A-Za-z]{2,6}$/,  // 邮箱
    'IDcard': /(^\d{15}$)|(^\d{17}([0-9]|X)$)/,  // 身份证
    // 常用规则
    'needNumStr': /(?=.*[\d])?(?=.*[a-zA-Z])(?=.*[\d])/,  // 必须包含数字和字母
    // 常用规则反向
    'no-ZHCN': /[\u4E00-\u9FA5]/g,  // 不能输入中文
    'no-Space': /^ +| +$/g.test(info),  // 首尾端不能输入空格
  }

  if (typeof sign === 'string') {
    return sign.includes('no-') ? !signRegDic[sign].test(info) : signRegDic[sign].test(info);

  } else if (Array.isArray(sign)) {
    let result = true;
    sign.forEach(el => {
      const res = el.includes('no-') ? !signRegDic[el].test(info) : signRegDic[el].test(info);
      if (!res) {
        result = false;
      }
    });
    return result

  } else {
    return false
  }
}

/** 返回富文本HTML格式字数
 * @param html 代表 富文本HTML格式
 **/ 
export const getTextWordCount = (html: string) => {
  // 使用正则表达式去除HTML标签和空格
  const text = html.replace(/(<([^>]+)>)/gi, '').replace(/[\s]/gi, '')
  return text.length
}

/** 
 * 处理模板字符串，变量包裹字符：{{ var }}
 * @param text 处理文本
 * @param variables 匹配变量对象
 * @param replace 匹配失败时替换文字
 * @param leftDelimiter 左包裹特殊字符
 * @param leftDelimiter 左包裹特殊字符
 **/ 
export const repalceVaribles = (
  text: string, 
  variables: {[key: string]: any}, 
  replace: string | boolean = false,
  leftDelim: string = '{{', 
  rightDelim: string = '}}'
) => {
  const escapeRegExp = str => str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
  const pattern = new RegExp(`${escapeRegExp(leftDelim)}(\\s*\\w+\\s*)${escapeRegExp(rightDelim)}`, 'g');
  return text.replace(pattern, (match, varName) => variables[varName.trim()] ?? (replace === false ? match : replace));
};
